package org.hd2.util.audio;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import java.io.*;
import java.nio.channels.NonReadableChannelException;
import java.util.logging.Logger;

public class MicAdjust extends Activity {
    SeekBar hsMicGain, spkMicGain, headsMicGain, btMicGain;
    TextView hsMicGainV, spkMicGainV, btMicGainV, headsMicGainV;
    static final int HS_MIC_GAIN_DEF = 200;
    static final int SPK_MIC_GAIN_DEF = 400;
    static final int HEAD_MIC_GAIN_DEF = 100;
    static final int BT_MIC_GAIN_DEF = 100;
    SharedPreferences spref;
    final String LOG_TAG = "MicAdjust";
    final int MULTIPLIER = 25;

    Process proc;
    OutputStream outStream;
    Reader rdr, rdrErr;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        if (isMicTunable()) {

            hsMicGain = (SeekBar) findViewById(R.id.hsMicGain);
            spkMicGain = (SeekBar) findViewById(R.id.spkMicGain);
            headsMicGain = (SeekBar) findViewById(R.id.headsMicGain);
            btMicGain = (SeekBar) findViewById(R.id.btMicGain);
            
            hsMicGainV = (TextView) findViewById(R.id.hsMicGainV);
            spkMicGainV = (TextView) findViewById(R.id.spkMicGainV);
            headsMicGainV = (TextView) findViewById(R.id.headsMicGainV);
            btMicGainV = (TextView) findViewById(R.id.btMicGainV);

            spref = PreferenceManager.getDefaultSharedPreferences(this);
            int test = spref.getInt("HS_MIC_GAIN", HS_MIC_GAIN_DEF);
            hsMicGainV.setText(spref.getInt("HS_MIC_GAIN", HS_MIC_GAIN_DEF) + "");
            spkMicGainV.setText(spref.getInt("SPK_MIC_GAIN", SPK_MIC_GAIN_DEF) + "");
            headsMicGainV.setText(spref.getInt("HEAD_MIC_GAIN", HEAD_MIC_GAIN_DEF) + "");
            btMicGainV.setText(spref.getInt("BT_MIC_GAIN", BT_MIC_GAIN_DEF) + "");

            hsMicGain.setProgress((spref.getInt("HS_MIC_GAIN", HS_MIC_GAIN_DEF) - HS_MIC_GAIN_DEF)/MULTIPLIER);
            spkMicGain.setProgress((spref.getInt("SPK_MIC_GAIN", SPK_MIC_GAIN_DEF) - SPK_MIC_GAIN_DEF)/MULTIPLIER);
            headsMicGain.setProgress((spref.getInt("HEAD_MIC_GAIN", HEAD_MIC_GAIN_DEF) - HEAD_MIC_GAIN_DEF)/MULTIPLIER);
            btMicGain.setProgress((spref.getInt("BT_MIC_GAIN", BT_MIC_GAIN_DEF) - BT_MIC_GAIN_DEF)/MULTIPLIER);

            handleChanges();
        }else{
            findViewById(R.id.error).setVisibility(View.VISIBLE);
            findViewById(R.id.ctrls).setVisibility(View.GONE);
        }
    }

    private Boolean isMicTunable(){
        File file = new File("/proc/mic_level");
        File dbg = new File("/mnt/sdcard/vzdebug.txt");
        if(file.exists() || dbg.exists())
            return true;
        else
            return false;
    }

    private void handleChanges() {
        hsMicGain.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                hsMicGainV.setText(HS_MIC_GAIN_DEF + i * MULTIPLIER + "");
            }

            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            public void onStopTrackingTouch(SeekBar seekBar) {
                SharedPreferences.Editor editor = spref.edit();
                editor.putInt("HS_MIC_GAIN", HS_MIC_GAIN_DEF + seekBar.getProgress() * MULTIPLIER );
                editor.commit();
                save(String.format("echo '0 %s' > /proc/mic_level", HS_MIC_GAIN_DEF + seekBar.getProgress() * MULTIPLIER));
            }
        });


        spkMicGain.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                spkMicGainV.setText(SPK_MIC_GAIN_DEF + i * MULTIPLIER+ "");
            }

            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            public void onStopTrackingTouch(SeekBar seekBar) {
                SharedPreferences.Editor editor = spref.edit();
                editor.putInt("SPK_MIC_GAIN", SPK_MIC_GAIN_DEF + seekBar.getProgress() * MULTIPLIER);
                editor.commit();
                save(String.format("echo '1 %s' > /proc/mic_level", SPK_MIC_GAIN_DEF + seekBar.getProgress() * MULTIPLIER));
            }
        });

        headsMicGain.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                headsMicGainV.setText(HEAD_MIC_GAIN_DEF + i * MULTIPLIER + "");
            }

            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            public void onStopTrackingTouch(SeekBar seekBar) {
                SharedPreferences.Editor editor = spref.edit();
                editor.putInt("HEAD_MIC_GAIN", HEAD_MIC_GAIN_DEF + seekBar.getProgress() * MULTIPLIER);
                editor.commit();
                save(String.format("echo '2 %s' > /proc/mic_level", HEAD_MIC_GAIN_DEF + seekBar.getProgress() * MULTIPLIER));
            }
        });

        btMicGain.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                btMicGainV.setText(BT_MIC_GAIN_DEF + i * MULTIPLIER + "");
            }

            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            public void onStopTrackingTouch(SeekBar seekBar) {
                SharedPreferences.Editor editor = spref.edit();
                editor.putInt("BT_MIC_GAIN", BT_MIC_GAIN_DEF + seekBar.getProgress() * MULTIPLIER);
                editor.commit();
                save(String.format("echo '4 %s' > /proc/mic_level", BT_MIC_GAIN_DEF + seekBar.getProgress() * MULTIPLIER));
            }
        });
    }

    private void cancel(View v) {
        this.finish();
    }

    @Override
    public void onDestroy() {
        try {

            try {
                if (outStream != null) {
                    outStream.close();
                }
            } catch (Exception ex) {
            }

            if (proc != null) {
                proc.destroy();
            }

            if (rdr != null) rdr.stop();
            if (rdrErr != null) rdrErr.stop();

        } catch (Exception ex) {
        }

        super.onDestroy();
    }

    public void savePermanently(View v) {
        AlertDialog.Builder alertbox = new AlertDialog.Builder(this);

        alertbox.setMessage("Do you really want to save settings to /etc/init.d/10mic_level?\n");
        alertbox.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface arg0, int arg1) {
                String permanent = "";
                permanent += String.format("#!/system/bin/sh\n");
                permanent += String.format("# This file was automatically generated by HD2 Mic Gain Control app.\n\n");
                permanent += String.format("echo '0 %s' > /proc/mic_level\n", HS_MIC_GAIN_DEF + hsMicGain.getProgress() * MULTIPLIER);
                permanent += String.format("echo '1 %s' > /proc/mic_level\n", SPK_MIC_GAIN_DEF + spkMicGain.getProgress() * MULTIPLIER);
                permanent += String.format("echo '2 %s' > /proc/mic_level\n", HEAD_MIC_GAIN_DEF + headsMicGain.getProgress() * MULTIPLIER);
                permanent += String.format("echo '4 %s' > /proc/mic_level\n", BT_MIC_GAIN_DEF + btMicGain.getProgress() * MULTIPLIER);
                permanent = String.format("echo \"%s\" > /etc/init.d/10mic_level", permanent);

                save(permanent);
                //remove old file
                save("rm /etc/init.d/989miclevel");
                save("chmod 750 /etc/init.d/10mic_level");
                Toast.makeText(getApplicationContext(), "Saved to /etc/init.d/10mic_level.", Toast.LENGTH_SHORT).show();
            }
        });
        alertbox.setNegativeButton("No", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface arg0, int arg1) {
            }
        });

        alertbox.show();
    }

    private void save(String cmd) {

        try {
            if (proc == null) {
                proc = Runtime.getRuntime().exec("su");
                outStream = proc.getOutputStream();
                // not really required except for debugging?
                //rdr = new Reader(proc.getInputStream());
                //rdrErr = new Reader(proc.getErrorStream());
                //rdr.start();
                //rdrErr.start();
            }

            cmd = cmd + "\n";
            byte[] bcmd = (cmd).getBytes("ASCII");
            Log.d(LOG_TAG, cmd);
            outStream.write(bcmd);
            //Toast.makeText(getApplicationContext(), cmd, Toast.LENGTH_SHORT).show();

        } catch (Exception ex) {
            Log.e(LOG_TAG, "Error setting mic gain. " + Log.getStackTraceString(ex));
        }

    }

    public void goXDA(View v){
        String url = "http://forum.xda-developers.com/showthread.php?t=1162224#";
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setData(Uri.parse(url));
        startActivity(i);
    }

    class Reader extends Thread {
        InputStream is;

        Reader(InputStream is) {
            this.is = is;
        }

        public void run() {
            try {
                InputStreamReader inStreamReader = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(inStreamReader);
                String line = null;
                while ((line = br.readLine()) != null) {
                    Log.d(LOG_TAG, "out: " + line);
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}


